package logger

import (
	"gitee.com/zhouhailin/gopkg/gofile"
	"gitee.com/zhouhailin/gopkg/goxml"
	"strconv"
	"strings"
)

func init() {
	if gofile.IsFile("etc/logger.xml") {
		ReadConfigurationInFile("etc/logger.xml")
	} else if gofile.IsFile("config/logger.xml") {
		ReadConfigurationInFile("config/logger.xml")
	}
}

func replaceHolder(value string, property map[string]string) string {
	for k, v := range property {
		value = strings.ReplaceAll(value, "${"+k+"}", v)
	}
	return value
}

func addAppenderElement(property map[string]string, element *goxml.Element) {
	if element.Attributes["type"] == "ConsoleAppender" {
		for _, el1 := range element.Elements {
			if el1.Name == "encoder" {
				for _, el2 := range el1.Elements {
					if el2.Name == "pattern" && el2.Text != "" {
						AddAppender(NewConsoleAppender(element.Attributes["name"], el2.Text))
					}
				}
			}
		}
	} else if element.Attributes["type"] == "FileAppender" {
		var pattern, file string
		for _, ele := range element.Elements {
			if ele.Name == "file" && ele.Text != "" {
				file = replaceHolder(ele.Text, property)
			} else if ele.Name == "encoder" {
				for _, el2 := range ele.Elements {
					if el2.Name == "pattern" && el2.Text != "" {
						pattern = el2.Text
					}
				}
			}
		}
		if pattern != "" && file != "" {
			AddAppender(NewFileAppender(element.Attributes["name"], pattern, file))
		}
	} else if element.Attributes["type"] == "RollingFileAppender" {
		var pattern, file string
		var rollingPolicy *SizeAndTimeBasedRollingPolicy
		for _, ele := range element.Elements {
			if ele.Name == "file" && ele.Text != "" {
				file = replaceHolder(ele.Text, property)
			} else if ele.Name == "encoder" {
				for _, el2 := range ele.Elements {
					if el2.Name == "pattern" && el2.Text != "" {
						pattern = el2.Text
					}
				}
			} else if ele.Name == "rollingPolicy" && ele.Attributes["type"] == "SizeAndTimeBasedRollingPolicy" {
				rollingPolicy = &SizeAndTimeBasedRollingPolicy{
					MaxHistory: 60,
					Compress:   true,
				}
				for _, ele2 := range ele.Elements {
					if ele2.Name == "pattern" && ele2.Text != "" {
						rollingPolicy.Pattern = ele2.Text
					} else if ele2.Name == "maxFileSize" && ele2.Text != "" {
						rollingPolicy.MaxFileSize = ele2.Text
					} else if ele2.Name == "maxHistory" && ele2.Text != "" {
						val, err := strconv.Atoi(ele2.Text)
						if err == nil {
							rollingPolicy.MaxHistory = val
						}
					} else if ele2.Name == "compress" && ele2.Text != "" {
						rollingPolicy.Compress = ele2.Text == "true"
					}
				}
			}
		}
		if pattern != "" && file != "" && rollingPolicy != nil {
			AddAppender(NewRollingFileAppender(element.Attributes["name"], file, pattern, rollingPolicy))
		}
	}
}

func ReadConfigurationInFile(file string) {
	rootElement := goxml.DecodeXmlFile(file)
	if rootElement == nil || rootElement.Name != "configuration" {
		return
	}
	property := make(map[string]string)
	for _, element := range rootElement.Elements {
		if element.Name == "appender" && element.Attributes["name"] != "" {
			addAppenderElement(property, element)
		} else if element.Name == "logger" && element.Attributes["name"] != "" && element.Attributes["level"] != "" {
			var refs []string
			for _, el := range element.Elements {
				if el.Name == "appender-ref" && el.Attributes["ref"] != "" {
					refs = append(refs, el.Attributes["ref"])
				}
			}
			if len(refs) > 0 {
				AddLoggerAppender(element.Attributes["name"], element.Attributes["level"], element.Attributes["additivity"] == "true", refs...)
			}
		} else if element.Name == "root" && element.Attributes["level"] != "" {
			var refs []string
			for _, el := range element.Elements {
				if el.Name == "appender-ref" && el.Attributes["ref"] != "" {
					refs = append(refs, el.Attributes["ref"])
				}
			}
			if len(refs) > 0 {
				AddRootLoggerAppender(element.Attributes["level"], refs...)
			}
		} else if element.Name == "property" && element.Attributes["name"] != "" && element.Attributes["value"] != "" {
			property[element.Attributes["name"]] = element.Attributes["value"]
		}
	}

}
